package com.th.apicenter.cainiao.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.taobao.pac.sdk.cp.dataobject.request.CN_QUERY_POPULARIZE_MATERIAL.PopularizeMaterialGenerateRequest;
import com.th.apicenter.cainiao.EncryptUtil;
import com.th.apicenter.cainiao.dto.CainiaoRequestDTO;
import com.th.apicenter.cainiao.entity.ThCainiaoData;
import com.th.apicenter.cainiao.vo.MaterialModel;
import com.th.apicenter.config.ApplicationProperties;
import com.th.apicenter.mapper.ThCainiaoDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class CainiaoService {

    @Autowired
    private ApplicationProperties applicationProperties;

    @Resource
    private ThCainiaoDataMapper thCainiaoDataMapper;

    private static final Gson gson = new Gson();

    /**
     * 获取推⼴素材
     */
    public List<ThCainiaoData> getPopularizeMaterial() {

        String linkUrl = applicationProperties.getCaiNiao().getLinkUrl();
        String secretkey = applicationProperties.getCaiNiao().getSecretkey();
        String cpCode = applicationProperties.getCaiNiao().getCpCode();
        String msgType = "CN_QUERY_POPULARIZE_MATERIAL";

        CainiaoRequestDTO<PopularizeMaterialGenerateRequest> cainiaoRequestDTO = new CainiaoRequestDTO<>();
        PopularizeMaterialGenerateRequest request = new PopularizeMaterialGenerateRequest();
        request.setAccessType("link");
        request.setPopularizeSource("cps");
        request.setProductCode("sendPackage");
        Map featureMap = new HashMap();
        featureMap.put("element", "test");
        request.setFeature(featureMap);
        request.setCnUnionId(applicationProperties.getCaiNiao().getCnUnionId());
        request.setSiteId("123456");
        request.setSiteName("菜鸟裹裹微信寄件小程序");
        Map paramsMap = new HashMap();
        paramsMap.put("element", "psid");
        request.setParams(paramsMap);
        request.setMaterialTerminal("WE_CHAT_MINI_PROGRAM");
        cainiaoRequestDTO.setRequest(request);

        List<MaterialModel> materialList = new ArrayList<>();
        List<ThCainiaoData> list = new ArrayList<>();

        try {
            // 步骤1：生成数据签名
            String jsonContent = gson.toJson(cainiaoRequestDTO);
            String digest = EncryptUtil.DoSign(jsonContent, "utf-8", secretkey);

            // 步骤2：构建POST请求体
            String postData = buildPostData(jsonContent, digest, cpCode, msgType);

            // 步骤3：发送请求
            String response = sendPostRequest(linkUrl, postData);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(response);
            JsonNode resultNode = rootNode.get("result");
            if (null != resultNode) {
                JsonNode dataNode = resultNode.get("data");
                if (null != dataNode && "\"true\"".equals(resultNode.get("success").toString())) {
                    JsonNode materialModelList = dataNode.get("materialModelList");
                    ObjectMapper objectMapper = new ObjectMapper();
                    materialList = objectMapper.readValue(materialModelList.toString(), mapper.getTypeFactory().constructCollectionType(List.class, MaterialModel.class));
                    thCainiaoDataMapper.updateEffective();
                }
            }

            for (MaterialModel materialModel : materialList) {

                for (Object o : materialModel.getContentList()) {
                    ThCainiaoData thCainiaoData = new ThCainiaoData();
                    thCainiaoData.setTerminal(materialModel.getTerminal());
                    thCainiaoData.setType(materialModel.getType());
                    thCainiaoData.setContent(String.valueOf(o));
                    thCainiaoData.setCreateTime(new Date());
                    thCainiaoDataMapper.insert(thCainiaoData);
                    list.add(thCainiaoData);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }


    // 构建POST参数
    private static String buildPostData(String jsonContent, String digest,
                                        String cpCode, String msgType)
            throws Exception {
        return "msg_type=" + encodeValue(msgType) +
                "&logistics_interface=" + encodeValue(jsonContent) +
                "&data_digest=" + encodeValue(digest) +
                "&logistic_provider_id=" + encodeValue(cpCode);
    }

    // URL编码工具方法
    private static String encodeValue(String value) throws Exception {
        return URLEncoder.encode(value, StandardCharsets.UTF_8.name());
    }

    // 发送POST请求
    private static String sendPostRequest(String url, String postData)
            throws IOException {
        HttpURLConnection conn = null;
        try {
            URL requestUrl = new URL(url);
            conn = (HttpURLConnection) requestUrl.openConnection();

            // 配置请求头
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setDoOutput(true);

            // 写入请求体
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = postData.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }

            // 读取响应
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    return response.toString();
                }
            } else {
                throw new IOException("HTTP error code: " + conn.getResponseCode());
            }
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }
}
